package com.koron.operation.classes.schedule.controller;


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.github.pagehelper.PageInfo;
import com.koron.bean.base.Response;
import com.koron.bean.query.PageQuery;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.EasyExcelUtils;
import com.koron.operation.classes.schedule.bean.converter.ScheduleConverter;
import com.koron.operation.classes.schedule.bean.dto.ClassesScheduleDTO;
import com.koron.operation.classes.schedule.bean.dto.ClassesShiftDTO;
import com.koron.operation.classes.schedule.bean.dto.ScheduleDTO;
import com.koron.operation.classes.schedule.bean.po.ClassesSchedule;
import com.koron.operation.classes.schedule.bean.query.ScheduleQuery;
import com.koron.operation.classes.schedule.excelHandler.ScheduleWriteHandler;
import com.koron.operation.classes.schedule.service.ClassesScheduleService;
import com.koron.operation.classes.shift.task.ShiftTask;
import com.koron.operation.util.OperationCodeTools;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import org.koron.ebs.mybatis.ADOConnection;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;
import java.util.*;

/**
 * 排班方案(ClassesSchedule)表控制层
 *
 * @author jzp
 * @since 2021-10-20 16:20:35
 */
@Api(tags = "排班方案接口")
@RestController
@RequestMapping("schedule")
public class ScheduleController {
    /**
     * 服务对象
     */
    @Autowired
    private ClassesScheduleService classesScheduleService;

    @Autowired
    private ShiftTask shiftTask;

    private String getCurrDs() {
        return ThreadLocalContext.get().getCurrDs();
    }

    @ApiOperation(value = "分页")
    @GetMapping("page")
    public Response<PageInfo<ClassesSchedule>> page(PageQuery pageQuery, ScheduleQuery query) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), classesScheduleService, "page", PageInfo.class, pageQuery, query));
    }

    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @ApiOperation(value = "根据id查询")
    @GetMapping
    public Response<ScheduleDTO> selectOne(@RequestParam String id) {
        return Response.ok(ADOConnection.runTask(getCurrDs(), classesScheduleService, "getDtoById", ScheduleDTO.class, id));
    }

    @ApiOperation(value = "保存时查询是否有重复排班方案，返回重复的排班方案")
    @PostMapping("hasDuplicate")
    public Response<List<ClassesSchedule>> hasDuplicate(@RequestBody ScheduleDTO scheduleDTO) {
        List<ClassesSchedule> hasDuplicate = ADOConnection.runTask(getCurrDs(), classesScheduleService, "hasDuplicate", List.class, scheduleDTO);
        return Response.ok(hasDuplicate);
    }

    @ApiOperation(value = "保存或更新数据")
    @PostMapping
    public Response<String> save(@RequestBody ScheduleDTO scheduleDTO) {
        ADOConnection.runTask(getCurrDs(), classesScheduleService, "saveOrUpdateDto", Boolean.class, scheduleDTO);
        // 创建自动交接班计划
        shiftTask.createTask(scheduleDTO, getCurrDs());
        return Response.ok(scheduleDTO.getId());
    }

    @ApiOperation(value = "删除数据")
    @DeleteMapping
    public Response<String> delete(@RequestParam String id) {
        ClassesSchedule classesSchedule = ADOConnection.runTask(getCurrDs(), classesScheduleService, "getById", ClassesSchedule.class, id);
        ADOConnection.runTask(getCurrDs(), classesScheduleService, "deleteById", Boolean.class, id);
        if (classesSchedule != null && Objects.equals(classesSchedule.getAutoSwitch(), 0)) {
            return Response.ok();
        }
        // 删除自动交接班计划
        shiftTask.deleteTask(id);
        shiftTask.deleteTopicTask(id);
        return Response.ok();
    }

    @ApiOperation(value = "停用或启用", notes = "0启用，1停用")
    @PutMapping("stopOrStart")
    public Response<String> stopOrStart(@RequestParam String id, @RequestParam Integer status) {
        ADOConnection.runTask(getCurrDs(), classesScheduleService, "updateStatus", Boolean.class, id, status);
        ClassesSchedule classesSchedule = ADOConnection.runTask(getCurrDs(), classesScheduleService, "getById", ClassesSchedule.class, id);
        if (classesSchedule.getAutoSwitch() == 0) {
            return Response.ok();
        }
        // 如果是停用，删除任务
        if (status == 1) {
            shiftTask.deleteTask(id);
            shiftTask.deleteTopicTask(id);
        } else {
            shiftTask.createTask(id, getCurrDs());
            shiftTask.startTopicTask(id);
        }
        return Response.ok();
    }

    @SneakyThrows
    @ApiOperation(value = "下载模板")
    @GetMapping("template")
    public void template(@RequestParam String id, HttpServletResponse response) {
        ScheduleDTO scheduleDTO = ADOConnection.runTask(getCurrDs(), classesScheduleService, "getDtoById", ScheduleDTO.class, id);

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode(scheduleDTO.getName(), "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        List<List<String>> head = new ArrayList<>();
        head.add(Arrays.asList("值班开始时间", "值班开始时间"));
        head.addAll(ScheduleConverter.getScheduleHead(scheduleDTO));

        ExcelWriter excelWriter = null;
        try {
            excelWriter = EasyExcel.write(response.getOutputStream()).inMemory(true).build();
            WriteSheet writeSheet0 = EasyExcel
                    .writerSheet(0, scheduleDTO.getName())
                    .registerWriteHandler(new ScheduleWriteHandler(scheduleDTO))
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                    .head(head)
                    .build();

            WriteSheet writeSheet1 = EasyExcel
                    .writerSheet(1, "人员填写说明")
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                    .build();

            excelWriter.write(Collections.emptyList(), writeSheet0);
            excelWriter.write(ScheduleConverter.getScheduleExcelReadMe(), writeSheet1);
        }finally {
            // 千万别忘记finish 会帮忙关闭流
            if (excelWriter != null) {
                excelWriter.finish();
            }
        }

    }

    @SneakyThrows
    @ApiOperation(value = "导入")
    @PostMapping("import")
    public Response importFile(@RequestParam String id, @RequestParam("file") MultipartFile file) {
        ScheduleDTO scheduleDTO = ADOConnection.runTask(getCurrDs(), classesScheduleService, "getDtoById", ScheduleDTO.class, id);

        List<List<String>> head = new ArrayList<>();
        head.add(Arrays.asList("值班开始时间", "值班开始时间"));
        head.addAll(ScheduleConverter.getScheduleHead(scheduleDTO));

        String filename = OperationCodeTools.getScheduleShiftTemp();
        String tempPath = EasyExcelUtils.createTempFile(filename, "xlsx");

        List<Map<Integer, String>> data = EasyExcel.read(file.getInputStream()).sheet(scheduleDTO.getName()).headRowNumber(2).doReadSync();
        Assert.notEmpty(data, "未检测到数据，可能是sheet【" + scheduleDTO.getName() + "】不存在");
        ScheduleWriteHandler scheduleWriteHandler = new ScheduleWriteHandler(scheduleDTO);

        EasyExcel.write(tempPath)
                .inMemory(true)
                .registerWriteHandler(scheduleWriteHandler)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .head(head)
                .sheet(scheduleDTO.getName())
                .doWrite(data);
        List<ClassesShiftDTO> classesShiftDTOS = scheduleWriteHandler.getClassesShiftDTOS();
        ClassesScheduleDTO classesScheduleDTO = new ClassesScheduleDTO();
        BeanUtils.copyProperties(scheduleDTO, classesScheduleDTO);
        classesScheduleDTO.setShifts(classesShiftDTOS);
        scheduleDTO.fromClassesScheduleDTO(classesScheduleDTO);
        if (scheduleWriteHandler.isHasError()) {
            return Response.ok("temp/" + filename + ".xlsx");
        }

        // 全覆盖
        return Response.ok(scheduleDTO.getShiftList());
    }

    @SneakyThrows
    @ApiOperation(value = "导出")
    @GetMapping("export")
    public void exportFile(@RequestParam String id, HttpServletResponse response) {
        ScheduleDTO scheduleDTO = ADOConnection.runTask(getCurrDs(), classesScheduleService, "getDtoById", ScheduleDTO.class, id);

        String filename = OperationCodeTools.getScheduleShiftTemp();
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode(scheduleDTO.getName(), "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        List<List<String>> head = new ArrayList<>();
        head.add(Arrays.asList("值班开始时间", "值班开始时间"));
        head.addAll(ScheduleConverter.getScheduleHead(scheduleDTO));
        EasyExcel.write(response.getOutputStream())
                .inMemory(true)
                .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                .head(head)
                .sheet(scheduleDTO.getName())
                .doWrite(ScheduleConverter.getScheduleData(scheduleDTO));
    }

}
